const cron = require('node-cron');
const config = require('../config/config');
const { setupLogger } = require('../utils/logger');
const dataService = require('./dataService');

class SchedulerService {
  constructor() {
    this.logger = setupLogger();
    this.tasks = new Map();
    this.isRunning = false;
  }

  start() {
    if (this.isRunning) {
      this.logger.warn('定时任务服务已在运行');
      return;
    }

    this.logger.info('启动定时任务服务...');
    
    // 数据刷新任务 - 每5分钟执行一次
    const dataRefreshTask = cron.schedule('*/5 * * * *', async () => {
      try {
        this.logger.info('开始定时数据刷新...');
        await dataService.refreshData();
        this.logger.info('定时数据刷新完成');
      } catch (error) {
        this.logger.error('定时数据刷新失败:', error);
      }
    }, {
      scheduled: false,
      timezone: 'Asia/Shanghai'
    });

    // 数据清理任务 - 每天凌晨2点执行
    const dataCleanupTask = cron.schedule('0 2 * * *', async () => {
      try {
        this.logger.info('开始定时数据清理...');
        await this.cleanupOldData();
        this.logger.info('定时数据清理完成');
      } catch (error) {
        this.logger.error('定时数据清理失败:', error);
      }
    }, {
      scheduled: false,
      timezone: 'Asia/Shanghai'
    });

    // 系统健康检查任务 - 每小时执行一次
    const healthCheckTask = cron.schedule('0 * * * *', async () => {
      try {
        this.logger.info('开始系统健康检查...');
        await this.performHealthCheck();
        this.logger.info('系统健康检查完成');
      } catch (error) {
        this.logger.error('系统健康检查失败:', error);
      }
    }, {
      scheduled: false,
      timezone: 'Asia/Shanghai'
    });

    // 数据备份任务 - 每6小时执行一次
    const backupTask = cron.schedule('0 */6 * * *', async () => {
      try {
        this.logger.info('开始数据备份...');
        await this.backupData();
        this.logger.info('数据备份完成');
      } catch (error) {
        this.logger.error('数据备份失败:', error);
      }
    }, {
      scheduled: false,
      timezone: 'Asia/Shanghai'
    });

    // 启动所有任务
    dataRefreshTask.start();
    dataCleanupTask.start();
    healthCheckTask.start();
    backupTask.start();

    // 保存任务引用
    this.tasks.set('dataRefresh', dataRefreshTask);
    this.tasks.set('dataCleanup', dataCleanupTask);
    this.tasks.set('healthCheck', healthCheckTask);
    this.tasks.set('backup', backupTask);

    this.isRunning = true;
    this.logger.info('定时任务服务启动完成');

    // 启动后立即执行一次数据刷新
    setTimeout(async () => {
      try {
        this.logger.info('执行初始数据刷新...');
        await dataService.refreshData();
        this.logger.info('初始数据刷新完成');
      } catch (error) {
        this.logger.error('初始数据刷新失败:', error);
      }
    }, 5000); // 5秒后执行
  }

  stop() {
    if (!this.isRunning) {
      this.logger.warn('定时任务服务未在运行');
      return;
    }

    this.logger.info('停止定时任务服务...');
    
    // 停止所有任务
    for (const [name, task] of this.tasks) {
      try {
        task.stop();
        this.logger.info(`已停止任务: ${name}`);
      } catch (error) {
        this.logger.error(`停止任务失败 ${name}:`, error);
      }
    }

    this.tasks.clear();
    this.isRunning = false;
    this.logger.info('定时任务服务已停止');
  }

  async cleanupOldData() {
    const fs = require('fs').promises;
    const path = require('path');
    
    try {
      // 清理超过7天的日志文件
      const logsDir = './logs';
      const files = await fs.readdir(logsDir);
      const now = Date.now();
      const sevenDaysAgo = now - (7 * 24 * 60 * 60 * 1000);

      for (const file of files) {
        const filePath = path.join(logsDir, file);
        const stats = await fs.stat(filePath);
        
        if (stats.mtime.getTime() < sevenDaysAgo) {
          await fs.unlink(filePath);
          this.logger.info(`已删除旧日志文件: ${file}`);
        }
      }

      // 清理旧的数据备份文件
      const dataDir = config.storage.dataDir;
      const dataFiles = await fs.readdir(dataDir);
      const backupFiles = dataFiles.filter(file => file.includes('backup_'));
      
      // 只保留最新的10个备份文件
      if (backupFiles.length > config.storage.maxBackups) {
        backupFiles.sort((a, b) => {
          const aTime = a.match(/backup_(\d+)/)?.[1] || '0';
          const bTime = b.match(/backup_(\d+)/)?.[1] || '0';
          return parseInt(bTime) - parseInt(aTime);
        });

        const filesToDelete = backupFiles.slice(config.storage.maxBackups);
        for (const file of filesToDelete) {
          const filePath = path.join(dataDir, file);
          await fs.unlink(filePath);
          this.logger.info(`已删除旧备份文件: ${file}`);
        }
      }

      this.logger.info('数据清理完成');
    } catch (error) {
      this.logger.error('数据清理失败:', error);
      throw error;
    }
  }

  async performHealthCheck() {
    try {
      const healthStatus = {
        timestamp: new Date().toISOString(),
        dataService: 'unknown',
        storage: 'unknown',
        memory: process.memoryUsage(),
        uptime: process.uptime(),
        cacheStats: {}
      };

      // 检查数据服务状态
      try {
        const lastUpdate = dataService.getLastUpdate();
        const cacheStats = dataService.getCacheStats();
        
        healthStatus.dataService = lastUpdate ? 'healthy' : 'warning';
        healthStatus.lastDataUpdate = lastUpdate;
        healthStatus.cacheStats = cacheStats;
      } catch (error) {
        healthStatus.dataService = 'error';
        healthStatus.dataServiceError = error.message;
      }

      // 检查存储状态
      try {
        const fs = require('fs').promises;
        const path = require('path');
        
        const jsonPath = path.join(config.storage.dataDir, config.storage.jsonFile);
        await fs.access(jsonPath);
        healthStatus.storage = 'healthy';
      } catch (error) {
        healthStatus.storage = 'error';
        healthStatus.storageError = error.message;
      }

      // 记录健康状态
      this.logger.info('系统健康状态:', healthStatus);

      // 如果内存使用过高，记录警告
      const memoryUsageMB = healthStatus.memory.heapUsed / 1024 / 1024;
      if (memoryUsageMB > 500) { // 超过500MB
        this.logger.warn(`内存使用过高: ${memoryUsageMB.toFixed(2)}MB`);
      }

      return healthStatus;
    } catch (error) {
      this.logger.error('健康检查失败:', error);
      throw error;
    }
  }

  async backupData() {
    if (!config.storage.backupEnabled) {
      this.logger.info('数据备份已禁用');
      return;
    }

    try {
      const fs = require('fs').promises;
      const path = require('path');
      
      const timestamp = Date.now();
      const sourceFile = path.join(config.storage.dataDir, config.storage.jsonFile);
      const backupFile = path.join(config.storage.dataDir, `backup_${timestamp}_${config.storage.jsonFile}`);
      
      // 检查源文件是否存在
      try {
        await fs.access(sourceFile);
      } catch (error) {
        this.logger.warn('源数据文件不存在，跳过备份');
        return;
      }

      // 复制文件
      await fs.copyFile(sourceFile, backupFile);
      this.logger.info(`数据备份完成: ${backupFile}`);

      // 同时备份Excel文件
      const excelSourceFile = path.join(config.storage.dataDir, config.storage.excelFile);
      try {
        await fs.access(excelSourceFile);
        const excelBackupFile = path.join(config.storage.dataDir, `backup_${timestamp}_${config.storage.excelFile}`);
        await fs.copyFile(excelSourceFile, excelBackupFile);
        this.logger.info(`Excel备份完成: ${excelBackupFile}`);
      } catch (error) {
        this.logger.warn('Excel文件不存在，跳过Excel备份');
      }

    } catch (error) {
      this.logger.error('数据备份失败:', error);
      throw error;
    }
  }

  getStatus() {
    return {
      isRunning: this.isRunning,
      taskCount: this.tasks.size,
      tasks: Array.from(this.tasks.keys())
    };
  }

  // 手动触发特定任务
  async triggerTask(taskName) {
    switch (taskName) {
      case 'dataRefresh':
        return await dataService.refreshData();
      case 'dataCleanup':
        return await this.cleanupOldData();
      case 'healthCheck':
        return await this.performHealthCheck();
      case 'backup':
        return await this.backupData();
      default:
        throw new Error(`未知任务: ${taskName}`);
    }
  }
}

module.exports = new SchedulerService();

